package com.ruoyi.system.http_utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.concurrent.FutureCallback;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.impl.nio.client.HttpAsyncClients;
import org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager;
import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor;
import org.apache.http.nio.reactor.ConnectingIOReactor;
import org.apache.http.nio.reactor.IOReactorException;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.net.URI;
import java.util.concurrent.CountDownLatch;

/**
 * @author xuezhenwei
 * @date 2025-03-19 16:36
 */

import java.util.ArrayList;
import java.util.List;

@Component
@Slf4j
public class AsyncHttpMultipleRequestsExample {
    public List<HttpResponse> asyncSend(List<URI> urls) throws IOReactorException {

        // 创建异步 HTTP 客户端

        ConnectingIOReactor ioReactor = new DefaultConnectingIOReactor();
        PoolingNHttpClientConnectionManager cm = new PoolingNHttpClientConnectionManager(ioReactor);

        // 设置最大连接数
        cm.setMaxTotal(100);
        // 设置每个路由的最大连接数
        cm.setDefaultMaxPerRoute(40);

        // 创建一个异步 HTTP 客户端，并使用连接池管理器
        CloseableHttpAsyncClient client = HttpAsyncClients.custom()
                .setConnectionManager(cm)
                .build();

//        CloseableHttpAsyncClient client = HttpAsyncClients.createDefault();
        client.start();

        // 用于等待所有请求完成的计数器
        CountDownLatch latch = new CountDownLatch(urls.size());
        // 存储所有响应的列表
        List<HttpResponse> responses = new ArrayList<>();

        for (URI url : urls) {
            // 创建 HTTP GET 请求
            HttpGet request = new HttpGet(url);

            // 执行异步请求
            client.execute(request, new FutureCallback<HttpResponse>() {
                @Override
                public void completed(HttpResponse response) {
                    // 请求成功完成，将响应添加到列表中
                    responses.add(response);
                    // 计数器减一
                    latch.countDown();
//                    log.info("Request to " + url + " completed. Status code: {}" , response.getStatusLine().getStatusCode());
                }

                @Override
                public void failed(Exception ex) {
                    // 请求失败，计数器减一
                    latch.countDown();
                    log.error("Request to {} failed: {}", url , ex.getMessage());
                }

                @Override
                public void cancelled() {
                    // 请求被取消，计数器减一
                    latch.countDown();
                    log.info("Request to {} cancelled." , url);
                }
            });
        }

        try {
            // 等待所有请求完成
            latch.await();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }

        // 关闭客户端
        try {
            client.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return responses;

    }
}
